package com.example.config;

import com.example.handler.MyAccessDeniedHandler;
import com.example.service.MyUserDetailsService;
import com.example.util.MyPasswordEncoder;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

import javax.annotation.Resource;


/**
 * security的认证权限配置类
 *
 * @EnableGlobalMethodSecurity(securedEnabled = true) ：开启基于方法级别的权限配置
 */
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Resource
    private MyPasswordEncoder encoder;

    @Resource
    private MyUserDetailsService userDetailsService;

    /**
     * 通过配置类自定义用户身份信息
     * AuthenticationManagerBuilder :认证管理构建器，用于构建用户认证
     * inMemoryAuthentication ：将用户认证信息保存到内存中
     * userDetailsService :指定自定义的认证逻辑（UserDetailsService）
     * passwordEncoder ：指定下密码编码器
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.
                userDetailsService(userDetailsService)
                .passwordEncoder(encoder)
        ;
    }

    @Resource
    private MyAccessDeniedHandler myAccessDeniedHandler;

    /**
     * 针对http请求做配置的
     * 比如：哪些资源需要认证，哪些不需要认证、自定义的登录页、退出、记住我......
     *  一般先配置放行资源、再配置需要特殊权限访问的资源，再配置剩余需要认证
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //自定义表单登录配置
        http.formLogin()
                .loginPage("/toLogin")    //自定义登录页
                .loginProcessingUrl("/login")    //登录请求
                .usernameParameter("username")
                .passwordParameter("password")
//                .successForwardUrl("/index") //登录成功后默认跳转的url
        ;

        //手动配置认证的资源
        http.authorizeRequests()
                .antMatchers("/toLogin", "/index")
                .permitAll();   //所有用户都可以访问
        //配置http资源需要的权限信息
        http.authorizeRequests()
                .antMatchers("/normal")
                .hasAnyRole("USER", "ADMIN")
                .antMatchers("/vip")
                .hasRole("ADMIN");
        //配置请求资源需要认证
        http.authorizeRequests()
                .anyRequest()
                .authenticated();

        //自定义拒绝访问处理器
        http.exceptionHandling().accessDeniedHandler(myAccessDeniedHandler);

        //关闭csrf防御机制
        http.csrf().disable();
    }
}
